



/**
 * GameData:{
 *     localData:{
 *         userid:xx,
 *         score:xx,
 *         userjson:{ }  // 是一个字符串
 *         localModel:{} // 挂上 G.localModel
 *
 *     },
 *     jsonData:{} // 和 userjson 是同一个引用
 *     playerData:{} // 指向 jsonData.playerData
 * }
 */

import ObjUtils from '../obj_utils';
import http from './HTTP';
import Types from '../types';

let GameData = {
    localData: null,  //所有的本地数据
    dbData: null,   //数据库返回数据
    jsonData: null,  //---本地数据中的json数据

    IsNewPlayer: true,  ///---是否有本地数据

    //-----------------------------
    // 数据存储方式
    Type:{
        NO_NETWORK:1, // 纯单机
        NETWORK:2,  // 数据需要上传到网络
    },

    _client:null,
    _saveType:0,

    // 玩家数据的引用
    _localModel:null,
    _playerModel:null,

    // 默认数据
    _localDefaultData:{}, // object
    _serverDefaultData:{}, // object


    //=================================
    // apis
    setDefaultData(localDefaultData,serverDefaultData){
        this._localDefaultData = localDefaultData;
        this._serverDefaultData = serverDefaultData;
    },
    loadData(client,type,cb) {

        this._client = client;
        this._saveType = type;

        // 微信下 需要获取玩家信息
        if(ShSdk.isWeChat()){
            let userInfo = this.getUserInfo();
            if(userInfo){
                this._client.setUserInfo(userInfo);
            }
        }

        if(this._saveType === this.Type.NO_NETWORK){
            // 只启用本地数据
            this._processLocal(cb);
        }else{
            // 需要处理网络
            this._processNetwork(cb);
        }
    },
    // getClient(){
    //     return this._client;
    // },

    /**
     * 本地数据
     * @return {object}
     */
    getLocalModel(){
        return this._localModel;
    },

    /**
     * 玩家数据
     * @return {object}
     */
    getPlayerModel(){
        return this._playerModel;
    },

    /**
     * 重新做一次引用.
     * @param realPlayerModel
     */
    reRefPlayerModel(realPlayerModel){
        this._playerModel = this.jsonData.playerData = realPlayerModel;
    },

    reRefLocalModel(realLocalModel){
        this._localModel = this.localData.localModel = realLocalModel;
    },

    /**
     * 玩家id {number}
     * @return {*}
     */
    getUserId() {
        if (this.localData && this.localData.userid) {
            return this.localData.userid;
        } else {
            return 0;
        }
    },

    /**
     * 游戏启动的时候,检查需要每日更新的数据
     */
    dailyDataCheck() {
        const SrcData = window.ShSdk.dailyConfig;
        this.DailyData = ObjUtils.deepClone(SrcData);

        let data = cc.sys.localStorage.getItem('daily');
        if (data) {
            let dailydata = JSON.parse(data);
            if (this.DailyData.stamp === dailydata.stamp) {
                this.DailyData = dailydata;  //----本地数据未过期，继续使用

                // 确保数据完整. 可能新发布的版本有新的字段添加
                for(let k in SrcData){
                    if(!(k in this.DailyData)){
                        this.DailyData[k] = SrcData[k];
                    }
                }

            } else {
                // 新的一天,数据 重置
                if (dailydata.playDay) {
                    this.DailyData.playDay = dailydata.playDay + 1;
                }
            }
        }
        this.saveLocalStorage('daily', JSON.stringify(this.DailyData));
    },

    /**
     * 获取当前 dailyData里面的 key 的值
     * @param key
     * @return {*}
     */
    getDailyData(key){
        if(key in this.DailyData){
            return this.DailyData[key];
        }else{
            cc.warn(`key:${key} do not in this.DailyData. 检查key是否正确!`);
        }
    },

    //----每天游戏数据更新
    dailyUpdate(key, newValue) {

        if(key in this.DailyData){
            this.DailyData[key] = newValue;
        }else{
            console.warn(`key:${key} do not in this.DailyData. 检查key是否正确!`);
        }
        this.saveLocalStorage('daily', JSON.stringify(this.DailyData));
    },

    // 用于排行榜
    setScore(s) {
        if (s > this.getScore()) {
            this.localData.score = s;
            this.saveData(3);
        }
    },

    getScore() {
        if (this.localData) {
            return this.localData.score || 0;
        }
        return 0;
    },

    ///----保存玩家的微信个人信息
    saveUserInfo(info) {
        this.saveLocalStorage('userinfo', JSON.stringify(info));
    },

    getUserInfo() {
        let data = cc.sys.localStorage.getItem('userinfo');
        if (data) {
            let userInfo = JSON.parse(data);
            return userInfo;
        }
        return null;
    },

    /**
     * 解决 APP-SERVICE-SDK:setStorageSync:fail; 错误
     * @param key
     * @param value
     * @constructor
     */
    saveLocalStorage(key,value){
        try {
            cc.sys.localStorage.setItem(key,value);
        }catch (e) {
            if(window.ShSdk.isWeChat()){
                console.log('微信同步存储出现问题,调用微信异步存储');
                wx.setStorage({key:key,data:value});
            }
        }
    },

    // 重置数据
    resetData(){
        this.jsonData = JSON.parse(this.localData.userjson) || {};

        this._localModel = this.localData.localModel = ObjUtils.deepClone(this._localDefaultData);
        this._playerModel = this.jsonData.playerData = ObjUtils.deepClone(this._serverDefaultData);
        this.saveData(3); // 同时上传数据到相应的平台
    },

    /**
     * 保存玩家数据. 默认都会保存到本地
     * @param code {number}
     *          2: 上传
     *          3: 上传,同时保存到相应的平台
     *          4. 只保存到相应的平台
     * @constructor
     */
    saveData(code) {
        if (this.localData) {
            this.localData.userjson = JSON.stringify(this.jsonData);
            //本地保存
            this.saveLocalStorage('userdata', JSON.stringify(this.localData));
            //上传服务器
            if (code == 2) {   // eslint-disable-line
                this._upload();
            } else if (code == 3) {   // eslint-disable-line
                //---上传微信
                this._client.saveToPlatform(this.localData);
                this._upload();
            } else if (code == 4) {   // eslint-disable-line
                this._client.saveToPlatform(this.localData);
            }
        }
    },

    _processLocal(cb){
        let localjson = cc.sys.localStorage.getItem('userdata');
        if(localjson){
            this.IsNewPlayer = false;
            this.localData = JSON.parse(localjson);
            this._dumpLocalData();
            setTimeout(cb,0);
        }else{
            // 直接认为是新玩家
            this.IsNewPlayer = true;
            this.localData = {
                userjson:'{}',
            };
            this._dumpLocalData();
            setTimeout(cb,0);
        }
    },
    _processNetwork(cb){
        // 初始化本地数据
        let localjson = cc.sys.localStorage.getItem('userdata');
        if (localjson) {
            this.IsNewPlayer = false;
            this.localData = JSON.parse(localjson);
            this._dumpLocalData();
            this._syncData();//读取本地数据后，检测是否需要同步

            if( this._client.checkServerData &&
                Types.isFunction(this._client.checkServerData)){
                this._client.checkServerData();
            }

            // trick: 不用等返回. 因为如果检查到数据更新,会直接弹框提示
            setTimeout(cb,0);
        }else{
            // 本地没有数据
            // 可能是新用户也可能是 老用户删除了数据
            this._client.login((ret)=>{
                if (ret.errcode == 0) {
                    this.dbData = ret.data;
                    if (!this.localData) {
                        this.localData = ret.data;
                        this._dumpLocalData();
                        this.saveData(3);
                    }
                    if(ret.data && ret.data.maxscore === 1){
                        GameData.UploadSyncFlag();
                    }
                    cb();
                }else{
                    // 登陆出错
                    console.log('loginErr:',ret);
                    this._client.onLoginError(ret);
                }
            });
        }
    },

    //-------------解析本地数据方便处理，初始化userjson中的数据字段
    _dumpLocalData() {
        this.jsonData = JSON.parse(this.localData.userjson) || {};

        // 虚拟出两个model
        // 一个 local 一个 server
        // local 全部保存在本地  server 全部保存在服务端

        // localModel
        if(!this.localData.localModel){
            this._localModel = this.localData.localModel  = ObjUtils.deepClone(this._localDefaultData);
        }else{
            this._localModel = this.localData.localModel;
        }

        // playerModel
        if(!this.jsonData.playerData){
            this._playerModel = this.jsonData.playerData = ObjUtils.deepClone(this._serverDefaultData);
        }else{
            this._playerModel = this.jsonData.playerData;
        }

        // 发送一个更新事件???
        ShSdk.onUpdateData();
    },

    //上传数据
    _upload() {

        //----上传服务器
        let upnames = ['userid', 'score', 'userjson']; //需要上传数据库的字段
        let data = {};
        for (let k in upnames) {
            data[upnames[k]] = this.localData[upnames[k]];
        }
        cc.log('上传的数据为:',data);
        http.Get('upload', data, ret => {
            if (ret.errcode == 0) {  // eslint-disable-line
                this.saveLocalStorage('datasync', 'ok');
            } else {
                this.saveLocalStorage('datasync', 'xxx');
            }
        });
    },

    /**
     * 更新同步标志
     * @constructor
     */
    UploadSyncFlag(){
        let data = {
            userid:this.getUserId(),
            maxscore:0
        };
        http.Get('upload', data, ret => { // eslint-disable-line
        });
    },

    /**
     * sex = 100 表示玩家是否已经完成了任务.
     * 1/2 表示初始值.  此方法用于重置sex,让其表示玩家还没有通过活动
     */
    UploadHolidayFlag(){
        let data = {
            userid:this.getUserId(),
            sex:1
        };
        http.Get('upload', data, ret => { // eslint-disable-line

        });
    },

    UploadNewYearPassedFlag(){
        let data = {
            userid:GameData.GetUserId(),
            sex:100, // 100 表示玩家 已经完成活动
        };
        http.Get('upload', data, ret => { // eslint-disable-line
            // if (ret.errcode == 0) {
            //     // cc.sys.localStorage.setItem('datasync', 'ok');
            //     GameData.SaveLocalStorage('datasync', 'ok');
            // } else {
            //     // cc.sys.localStorage.setItem('datasync', 'xxx');
            //     GameData.SaveLocalStorage('datasync', 'xxx');
            // }
        });
    },

    //如果之前上传数据失败，同步本地数据到数据库
    _syncData() {
        let sync = cc.sys.localStorage.getItem('datasync');
        if (sync != 'ok') {
            this._upload();
        }
    },

    // /**
    //  * 更新同步标志
    //  * @constructor
    //  */
    // UploadSyncFlag(){
    //     let data = {
    //         userid:this.GetUserId(),
    //         maxscore:0
    //     };
    //     http.Get('upload', data, ret => { // eslint-disable-line
    //         // if (ret.errcode == 0) {
    //         //     // cc.sys.localStorage.setItem('datasync', 'ok');
    //         //     GameData.SaveLocalStorage('datasync', 'ok');
    //         // } else {
    //         //     // cc.sys.localStorage.setItem('datasync', 'xxx');
    //         //     GameData.SaveLocalStorage('datasync', 'xxx');
    //         // }
    //     });
    // },
    //
};

export default GameData;

